<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <link rel="shortcut icon" href="./图标.png" type="image/x-icon">
    <title>贪吃蛇</title>
    <style>
        body {
            margin: 0%;
            padding: 0%;
        }

        .map {
            width: 900px;
            height: 600px;
            background-color: rgb(0, 0, 0);
            margin: 0% auto;
            position: relative;
            cursor: none;
        }

        .snake {
            width: 30px;
            height: 30px;
            position: absolute;
            border: 2px solid rgba(0, 0, 0, 0.226);
            box-sizing: border-box;
        }

        .food {
            position: absolute;
            width: 30px;
            height: 30px;
            background-color: aquamarine;
            border-radius: 50%;
        }

        .score {
            color: white;
        }
    </style>
</head>

<body>
    <script>
        var Map; //地图
        var Snake; //蛇
        var Food; //食物
        var score = 0; //分数
        var speed = 600; //蛇前进的速度
        var game = (function () { //单例模式开发

            function map() { //地图方法,用于创建地图和分数显示
                this._map = null;
                this.creatmap = function () { //创建地图
                    if (this._map == null) {
                        this._map = document.createElement('div');
                        this._map.className = 'map';
                    }
                }
                this.createSpan = function () {  //创建分数显示栏
                    this._span = null;
                    if (this._span == null) {
                        this._span = document.createElement("span");
                        this._span.className = "score";
                        this._span.innerHTML = "总分：0";
                    }
                    this._map.appendChild(this._span);//_span为_map的子集
                }
            }



            function snake() {//蛇的方法
                this.direct = 'right';//默认移动方向为向右
                this._map = null;
                this._span = null;
                this._snake = [//初始蛇有三块,头，身，尾，利用数组储存相对坐标,颜色和判断值
                    [3, 1, "red", null],
                    [2, 1, "orange", null],
                    [1, 1, "orange", null]
                ];
                this.creatsnake = function () { //创建蛇
                    for (var i = 0; i < this._snake.length; i++) {
                        if (this._snake[i][3] == null){
                            this._snake[i][3] = document.createElement('div');
                            this._snake[i][3].style.backgroundColor = this._snake[i][2];
                            this._snake[i][3].className = 'snake';
                        }
                        this._snake[i][3].style.left = this._snake[i][0] * 30 + 'px';//地图大小是900*600,蛇一节为30*30,推得结果
                        this._snake[i][3].style.top = this._snake[i][1] * 30 + 'px';
                        this._map.appendChild(this._snake[i][3]);//蛇的节是地图的子集
                    }

                }
                this.snake_move = function () {//蛇移动,坐标的迁移
                    var len = this._snake.length - 1;
                    for (var i = len; i > 0; i--) {
                        this._snake[i][1] = this._snake[i - 1][1];
                        this._snake[i][0] = this._snake[i - 1][0];
                    }
                    switch (this.direct) {//移动方向
                        case 'right':
                            this._snake[0][0] += 1;
                            break;
                        case 'left':
                            this._snake[0][0] -= 1;
                            break;
                        case 'top':
                            this._snake[0][1] += 1;
                            break;
                        case 'down':
                            this._snake[0][1] -= 1;
                            break;
                    }
                    // console.log(this._snake[0][3].style.left)
                    if (this._snake[0][0] == Food.x && this._snake[0][1] == Food.y) {//判断利用蛇头相对坐标和食物相对坐标是否迟到食物
                        score += 100;//吃到食物加分,满500分加速一次
                        console.log(this._span);
                        this._span.innerHTML = "总分:" + score + "分";
                        if (score % 500 == 0 && speed > 100) {
                            speed -= 100;
                            console.log(speed);
                            clearInterval(timecount);
                            setInterval(function () {
                                Snake.snake_move();
                            }, speed);


                        }
                        this._snake.push([//增加蛇长
                            this._snake[this._snake.length - 1][0],
                            this._snake[this._snake.length - 1][1],
                            "yellow",
                            null
                        ]);
                        Food.creatfood();//重新创建食物

                    }
                    if (this._snake[0][0] * 30 < 0 || this._snake[0][0] * 30 > 870 || this._snake[0][1] *
                        30 < 0 || this._snake[0][1] * 30 > 570) {//如果碰到墙壁,游戏结束
                        clearInterval(timecount);
                        this._span.innerHTML = 'GAME OVER';
                    }
                    this.creatsnake();

                }
            }


            function food() {//食物方法
                this._food = null;
                this.map = null;
                this.x = 0;
                this.y = 0;
                this.creatfood = function () {//类似于创建蛇
                    this.x = Math.floor(Math.random() * 30)
                    this.y = Math.floor(Math.random() * 20)
                    if (this._food == null) {
                        this._food = document.createElement('div');
                        this._food.className = 'food';
                    }
                    this._food.style.left = this.x * 30 + "px";
                    this._food.style.top = this.y * 30 + "px";
                    this._map.appendChild(this._food);//食物也是地图的子集
                }
            }

            function getmaps() {
                Map = new map;//实例化对象
                Map.creatmap();
                Map.createSpan();
                CreatFood(Map._map);//由于要用到map,所以不能直接调用"创建"方法,要穿对应的参,实现对map，span的使用
                CreatSnake(Map._map, Map._span);

                return Map._map;
            }

            function CreatFood(map) {//在地图上创建食物
                Food = new food;
                Food._map = map;
                Food.creatfood();
            }

            function CreatSnake(map, span) {//在地图上创建蛇,移动蛇
                Snake = new snake();
                Snake._map = map;
                Snake._span = span;
                Snake.creatsnake();
                timecount = setInterval(function () {
                    Snake.snake_move();
                }, speed);
                document.onkeypress = function (e) {//wasd 来控制蛇的方向(不能直接转换到相反方向)
                    switch (e.key) {
                        case 's':
                            if (Snake.direct == 'down'){
                                return;
                            }
                            Snake.direct = 'top';
                            break;
                        case 'a':
                            if (Snake.direct == 'right'){
                                return;
                            }
                            Snake.direct = 'left';
                            break;
                        case 'w':
                            if (Snake.direct == 'top'){
                                return;
                            }
                            Snake.direct = 'down';
                            break;
                        case 'd':
                            if (Snake.direct == 'left'){
                                return;
                            }
                            Snake.direct = 'right';
                            break;
                    }
                }
            }
            return {
                Snakemap : getmaps()
            }


        })();
        document.body.appendChild(game.Snakemap);//创建的所有是body的子集
        // console.log(Food.x);
    </script>
</body>
</html>